package com.smarthome.worker;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import com.smarthome.core.workingmonitor.WorkerService;
import com.smarthome.domain.bean.ShWorker;

/**
 * <B>任务管总调度</B> <br />
 * @author KongXiangyu
 */
@Service("workerManager")
public class WorkerManager {

    public static String job_group_name = "SMART_HOME";
    public final Logger logger = Logger.getLogger(this.getClass());
    @Resource
    private SchedulerFactoryBean schedulerFactoryBean;
    @Resource
    private WorkerService workerService;
    @Resource
    private Scheduler scheduler;

    @PostConstruct
    public void loadJobs() throws Exception {
        removeAllJobs();
        logger.info("WorkerManager-init...");
        // 这里获取任务信息数据
        List<ShWorker> shWorkers = workerService.getAliveWorkers();
        for (ShWorker worker : shWorkers) {
            WorkerJob job = new WorkerJob();
            job.setCronExpression(worker.getCronExpression());
            job.setDescription(worker.getRemark());
            job.setJobName(worker.getName());
            job.setMethodName(worker.getMethod());
            job.setSpringId(worker.getService());
            addJob(job);
        }
    }

    /**
     * 添加任务job
     * 
     * @param scheduleJob
     * @throws SchedulerException
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void addJob(WorkerJob job) throws SchedulerException {
        logger.info("WorkerManager-addJob...");
        if (job == null) {
            return;
        }
        logger.debug("...............................add_scheduler:" + scheduler);
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job_group_name);
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        if (null == trigger) { // 不存在，创建一个
            Class clazz = JobFactory.class;
            JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job_group_name).build();
            jobDetail.getJobDataMap().put("scheduleJob", job);
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
            trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job_group_name).withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } else {// Trigger已存在，那么更新相应的定时设置
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        }
    }

    /**
     * 获取所有计划中的任务列表
     * 
     * @return
     * @throws SchedulerException
     */
    public List<WorkerJob> getAllJob() throws SchedulerException {
        logger.info("WorkerManager-getAllJob...");
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
        List<WorkerJob> jobList = new ArrayList<WorkerJob>();
        for (JobKey jobKey : jobKeys) {
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
            for (Trigger trigger : triggers) {
                WorkerJob job = new WorkerJob();
                job.setJobName(jobKey.getName());
                job.setDescription("触发器:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                job.setCurrentJobStatus(triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    job.setCronExpression(cronExpression);
                }
                jobList.add(job);
            }
        }
        return jobList;
    }

    /**
     * 删除所有job
     * 
     */
    public void removeAllJobs() throws SchedulerException {
        logger.info("WorkerManager-removeAllJobs...");
        scheduler.clear();
    }

}